#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
XBot管理后台
"""

import os
import json
import asyncio
import aiofiles
from datetime import datetime, timedelta
from typing import Dict, Any, Optional, List
from flask import Flask, render_template, request, jsonify, session, redirect, url_for, flash
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
from werkzeug.security import generate_password_hash, check_password_hash
import qrcode
from io import BytesIO
import base64
import threading
import time
import glob
import traceback
import sqlite3
import logging
from logging.handlers import RotatingFileHandler

# 导入XBot相关模块
import sys
# 添加项目根目录到Python路径
current_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(current_dir)
sys.path.insert(0, project_root)

from common.logger import logger
from common.config_manager import ConfigManager
from plugins.plugin_manager import PluginManager
from api.xbot.login_api import LoginApi
from api.xbot.msg_api import MsgApi
from api.xbot.user_api import UserApi
from api.xbot.group_api import GroupApi
from api.xbot.friend_api import FriendApi
from database.messsagDB import MessageDB

app = Flask(__name__)
app.secret_key = 'xbot_admin_secret_key_2024'

# 确保JSON响应有正确的Content-Type
app.config['JSONIFY_MIMETYPE'] = 'application/json'
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False

# 初始化登录管理器
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'

# 用户数据文件
USERS_FILE = "admin_web/data/admin_users.json"

# 微信登录状态
wechat_login_status = {
    "is_logged_in": False,
    "user_info": None,
    "wxid": None,
    "qr_code": None,
    "qr_uuid": None,
    "qr_code_expires": None,
    "last_check": None
}

# 使用项目根目录的配置文件，重置单例实例
ConfigManager._instance = None
config_manager = ConfigManager(os.path.join(project_root, "config.properties"))

# 强制重新加载配置
config_manager.reload()
print(f"强制重新加载配置，配置文件路径: {config_manager.config_file}")
print(f"wxid: {config_manager.get_wxid()}")

# 直接修改配置文件路径
config_manager.config_file = os.path.join(project_root, "config.properties")
config_manager._load_config()
config_manager.api_config = config_manager._load_api_config()
print(f"直接修改后的配置文件路径: {config_manager.config_file}")
print(f"直接修改后的wxid: {config_manager.get_wxid()}")

# 初始化微信登录状态
def init_wechat_status():
    """初始化微信登录状态"""
    try:
        saved_wxid = config_manager.get_wxid()
        if saved_wxid:
            logger.info(f"初始化时发现配置文件中的wxid: {saved_wxid}")
            wechat_login_status.update({
                "is_logged_in": True,
                "wxid": saved_wxid,
                "user_info": {
                    "wxid": saved_wxid,
                    "nickname": "已登录用户",
                    "gender": 0,
                    "signature": "",
                    "avatar": "",
                    "country": "",
                    "province": "",
                    "city": "",
                    "mobile": "",
                    "alias": "",
                    "status": "初始化"
                },
                "last_check": time.time()
            })
            logger.info(f"微信登录状态初始化完成: {wechat_login_status}")
        else:
            logger.info("配置文件中没有wxid，保持未登录状态")
    except Exception as e:
        logger.error(f"初始化微信登录状态失败: {e}")

# 初始化微信登录状态
init_wechat_status()

class User(UserMixin):
    """用户类"""
    
    def __init__(self, user_id, username, password_hash):
        self.id = user_id
        self.username = username
        self.password_hash = password_hash

def load_users() -> Dict[str, Any]:
    """加载用户数据"""
    try:
        if os.path.exists(USERS_FILE):
            with open(USERS_FILE, 'r', encoding='utf-8') as f:
                return json.load(f)
    except Exception as e:
        logger.error(f"加载用户数据失败: {e}")
    
    return {"users": {}}

def save_users(users_data: Dict[str, Any]):
    """保存用户数据"""
    try:
        with open(USERS_FILE, 'w', encoding='utf-8') as f:
            json.dump(users_data, f, ensure_ascii=False, indent=2)
    except Exception as e:
        logger.error(f"保存用户数据失败: {e}")

def create_default_admin():
    """创建默认管理员账户"""
    try:
        users_data = load_users()
        if "admin" not in users_data.get("users", {}):
            users_data["users"]["admin"] = {
                "username": "admin",
                "password_hash": generate_password_hash("admin123"),
                "created_at": datetime.now().isoformat()
            }
            save_users(users_data)
            logger.info("默认管理员账户创建成功")
    except Exception as e:
        logger.error(f"创建默认管理员账户失败: {e}")

# 初始化：创建默认管理员账户
create_default_admin()

@login_manager.user_loader
def load_user(user_id):
    """加载用户"""
    users_data = load_users()
    user_data = users_data.get("users", {}).get(user_id)
    if user_data:
        return User(user_id, user_data["username"], user_data["password_hash"])
    return None

def save_login_status():
    """保存登录状态到文件"""
    try:
        status = {
            "is_logged_in": wechat_login_status["is_logged_in"],
            "wxid": wechat_login_status["wxid"],
            "user_info": wechat_login_status["user_info"],
            "login_time": time.time()
        }
        with open("login_status.json", "w", encoding="utf-8") as f:
            json.dump(status, f, ensure_ascii=False, indent=2)
        logger.info(f"登录状态已保存到文件，wxid: {wechat_login_status['wxid']}")
    except Exception as e:
        logger.error(f"保存登录状态失败: {e}")

def check_wechat_login_status(uuid=None):
    """检查微信登录状态"""
    import time
    now = time.time()
    logger.info(f"开始检查微信登录状态，uuid: {uuid}")
    
    # 初始化saved_wxid变量
    saved_wxid = ""
    
    try:
        # 首先从配置文件获取wxid
        saved_wxid = config_manager.get_wxid()
        logger.info(f"配置文件中的wxid: {saved_wxid}")
        
        if saved_wxid:
            # 如果有保存的wxid，通过user_get_profile验证是否真正在线
            logger.info(f"开始验证wxid: {saved_wxid}")
            verify_result = _verify_user_online(saved_wxid)
            logger.info(f"_verify_user_online返回结果: {verify_result}")
            
            if verify_result:
                logger.info(f"wxid {saved_wxid} 验证在线成功")
                logger.info(f"返回的wechat_login_status: {wechat_login_status}")
                return wechat_login_status
            else:
                # 不直接清空状态，只加 status 字段
                logger.warning(f"wxid {saved_wxid} 验证失败，保留上次状态，仅提示异常")
                if wechat_login_status.get("is_logged_in"):
                    if wechat_login_status.get("user_info"):
                        wechat_login_status["user_info"]["status"] = "验证失败"
                return wechat_login_status
        else:
            logger.info("配置文件中没有wxid")
        
        # 如果没有wxid或验证失败，检查二维码登录状态
        logger.info("检查二维码登录状态")
        qr_result = _check_qr_login_status(uuid)
        logger.info(f"二维码登录状态检查结果: {qr_result}")
        return qr_result
        
    except Exception as e:
        logger.error(f"检查微信登录状态失败: {e}")
        traceback.print_exc()
        # 异常情况下，如果配置文件中有wxid，也认为用户是登录的，但加status
        if saved_wxid:
            user_info = {
                "wxid": saved_wxid,
                "nickname": "未知（验证异常）",
                "gender": 0,
                "signature": "",
                "avatar": "",
                "country": "",
                "province": "",
                "city": "",
                "mobile": "",
                "alias": "",
                "status": "验证异常"
            }
            wechat_login_status.update({
                "is_logged_in": True,
                "wxid": saved_wxid,
                "user_info": user_info,
                "last_check": now
            })
            logger.info(f"异常情况下使用配置文件中的wxid: {saved_wxid}")
            logger.info(f"更新后的wechat_login_status: {wechat_login_status}")
            return wechat_login_status
        return wechat_login_status

def _verify_user_online(wxid: str) -> bool:
    """通过user_get_login_status接口验证用户是否在线"""
    import time
    now = time.time()
    logger.info(f"开始验证用户在线状态，wxid: {wxid}")
    try:
        api_base_url = config_manager.api_config.api_base_url
        logger.info(f"API地址: {api_base_url}")
        user_api = UserApi.init_no_wxid(api_base_url)
        
        # 调用user_get_login_status接口
        logger.info(f"调用user_get_login_status接口，wxid: {wxid}")
        try:
            login_status_result = user_api.user_get_login_status(wxid)
            logger.info(f"user_get_login_status完整结果: {login_status_result}")
        except Exception as api_error:
            logger.error(f"API调用失败: {api_error}")
            # API调用失败时，如果配置文件中有wxid，也认为用户是登录的，但加status
            if wxid:
                if wechat_login_status.get("user_info"):
                    wechat_login_status["user_info"]["status"] = "API调用失败"
                else:
                    user_info = {
                        "wxid": wxid,
                        "nickname": "未知（API调用失败）",
                        "gender": 0,
                        "signature": "",
                        "avatar": "",
                        "country": "",
                        "province": "",
                        "city": "",
                        "mobile": "",
                        "alias": "",
                        "status": "API调用失败"
                    }
                    wechat_login_status.update({
                        "is_logged_in": True,
                        "wxid": wxid,
                        "user_info": user_info,
                        "last_check": now
                    })
                logger.info(f"API调用失败，使用配置文件中的wxid: {wxid}")
                logger.info(f"更新后的wechat_login_status: {wechat_login_status}")
                return True
            return False
        
        # 检查是否成功
        if login_status_result.get("Success") or login_status_result.get("Code") == 0:
            logger.info("登录状态检查成功")
            data = login_status_result.get("Data", {})
            
            # 检查登录状态
            is_logged_in = data.get("IsLoggedIn", False)
            logger.info(f"API返回的登录状态: {is_logged_in}")
            
            if is_logged_in:
                # 如果在线，尝试获取用户信息
                try:
                    profile_result = user_api.user_get_profile(wxid)
                    logger.info(f"获取用户信息结果: {profile_result}")
                    
                    if profile_result.get("Success") or profile_result.get("Code") == 0:
                        profile_data = profile_result.get("Data", {})
                        user_info_data = profile_data.get("userInfo", {})
                        def get_string_value(field_data):
                            if isinstance(field_data, dict) and "string" in field_data:
                                return field_data["string"]
                            elif isinstance(field_data, str):
                                return field_data
                            else:
                                return ""
                        user_info = {
                            "wxid": wxid,
                            "nickname": get_string_value(user_info_data.get("nickname")),
                            "gender": user_info_data.get("gender", 0),
                            "signature": get_string_value(user_info_data.get("signature")),
                            "avatar": get_string_value(user_info_data.get("avatar")),
                            "country": get_string_value(user_info_data.get("country")),
                            "province": get_string_value(user_info_data.get("province")),
                            "city": get_string_value(user_info_data.get("city")),
                            "mobile": get_string_value(user_info_data.get("mobile")),
                            "alias": get_string_value(user_info_data.get("alias")),
                        }
                    else:
                        user_info = {
                            "wxid": wxid,
                            "nickname": "在线用户",
                            "gender": 0,
                            "signature": "",
                            "avatar": "",
                            "country": "",
                            "province": "",
                            "city": "",
                            "mobile": "",
                            "alias": ""
                        }
                except Exception as e:
                    logger.warning(f"获取用户信息失败: {e}")
                    user_info = {
                        "wxid": wxid,
                        "nickname": "在线用户",
                        "gender": 0,
                        "signature": "",
                        "avatar": "",
                        "country": "",
                        "province": "",
                        "city": "",
                        "mobile": "",
                        "alias": ""
                    }
                # 更新登录状态
                wechat_login_status.update({
                    "is_logged_in": True,
                    "wxid": wxid,
                    "user_info": user_info,
                    "last_check": now
                })
                logger.info(f"用户在线验证成功，昵称: {user_info['nickname']}")
                logger.info(f"更新后的wechat_login_status: {wechat_login_status}")
                return True
            else:
                logger.warning(f"用户未登录: {login_status_result}")
                # 只有API明确返回未登录时才清空状态
                wechat_login_status.update({
                    "is_logged_in": False,
                    "wxid": None,
                    "user_info": None,
                    "last_check": now
                })
                return False
        else:
            logger.warning(f"登录状态检查失败，详细结果: {login_status_result}")
            # API失败时不清空状态，只加status
            if wxid:
                if wechat_login_status.get("user_info"):
                    wechat_login_status["user_info"]["status"] = "需要验证"
                else:
                    user_info = {
                        "wxid": wxid,
                        "nickname": "未知（需要验证）",
                        "gender": 0,
                        "signature": "",
                        "avatar": "",
                        "country": "",
                        "province": "",
                        "city": "",
                        "mobile": "",
                        "alias": "",
                        "status": "需要验证"
                    }
                    wechat_login_status.update({
                        "is_logged_in": True,
                        "wxid": wxid,
                        "user_info": user_info,
                        "last_check": now
                    })
                logger.info(f"使用配置文件中的wxid: {wxid}，但需要验证在线状态")
                logger.info(f"更新后的wechat_login_status: {wechat_login_status}")
                return True
            logger.warning("API调用失败且没有wxid，返回False")
            return False
    except Exception as e:
        logger.error(f"验证用户在线状态异常: {e}")
        import traceback
        traceback.print_exc()
        # 异常情况下，如果配置文件中有wxid，也认为用户是登录的，但加status
        if wxid:
            if wechat_login_status.get("user_info"):
                wechat_login_status["user_info"]["status"] = "验证异常"
            else:
                user_info = {
                    "wxid": wxid,
                    "nickname": "未知（验证异常）",
                    "gender": 0,
                    "signature": "",
                    "avatar": "",
                    "country": "",
                    "province": "",
                    "city": "",
                    "mobile": "",
                    "alias": "",
                    "status": "验证异常"
                }
                wechat_login_status.update({
                    "is_logged_in": True,
                    "wxid": wxid,
                    "user_info": user_info,
                    "last_check": now
                })
            logger.info(f"异常情况下使用配置文件中的wxid: {wxid}")
            logger.info(f"更新后的wechat_login_status: {wechat_login_status}")
            return True
        logger.warning("异常情况下没有wxid，返回False")
        return False

def _check_qr_login_status(uuid=None):
    """检查二维码登录状态"""
    import time
    now = time.time()
    try:
        # 如果没有UUID，返回未登录状态
        if not uuid:
            return {
                "is_logged_in": False,
                "wxid": None,
                "user_info": None,
                "last_check": now
            }
        
        # 调用登录检查接口
        api_base_url = config_manager.api_config.api_base_url
        login_api = LoginApi.init_no_wxid(api_base_url)
        check_result = login_api.login_check_qr(uuid)
        
        logger.debug(f"二维码登录检查结果: {check_result}")
        
        # 检查是否登录成功
        if _is_login_successful(check_result.get("Message", ""), check_result):
            # 处理登录成功
            return _handle_login_success(check_result, login_api)
        else:
            # 处理传统状态检查
            return _handle_traditional_status(check_result)
            
    except Exception as e:
        logger.error(f"检查二维码登录状态失败: {e}")
        return {
            "is_logged_in": False,
            "wxid": None,
            "user_info": None,
            "last_check": now
        }

def _is_login_successful(message: str, check_data: dict) -> bool:
    """判断是否登录成功"""
    return message == "登录成功" or check_data.get("acctSectResp") is not None

def _handle_login_success(check_data: dict, login_api) -> dict:
    """处理登录成功"""
    import time
    now = time.time()
    acct_sect_resp = check_data.get("Data", {}).get('acctSectResp',{})
    
    wxid = acct_sect_resp.get("userName", "")
    user_info = {
        "nickname": acct_sect_resp.get("nickName", ""),
        "wxid": wxid,
        "mobile": acct_sect_resp.get("bindMobile", ""),
        "alias": acct_sect_resp.get("alias", "")
    }
    
    # 保存wxid到配置文件
    if wxid:
        config_manager.save_wxid(wxid)
    
    wechat_login_status.update({
        "is_logged_in": True,
        "wxid": wxid,
        "user_info": user_info,
        "last_check": now
    })
    
    save_login_status()
    _start_heartbeat(wxid, login_api)
    
    logger.info(f"微信登录成功，wxid: {wxid}, 昵称: {user_info['nickname']}")
    return wechat_login_status

def _handle_traditional_status(check_data: dict) -> dict:
    """处理传统状态码"""
    import time
    now = time.time()
    status = check_data.get("Status")
    logger.info(f"二维码状态: {status}")
    
    if status == 0:
        logger.info("等待用户扫码...")
    elif status == 1:
        logger.info("用户已扫码，等待确认...")
    elif status == 2:
        logger.info("用户已确认登录...")
    elif status == 3:
        logger.warning("二维码已过期...")
    elif status == 4:
        logger.warning("用户取消登录...")
    else:
        logger.info(f"未知状态: {status}")
    
    wechat_login_status["last_check"] = now
    return wechat_login_status

def _start_heartbeat(wxid: str, login_api):
    """开启自动心跳"""
    if not wxid:
        return
        
    try:
        heartbeat_result = login_api.login_auto_heart_beat(wxid)
        if heartbeat_result.get("Success") or heartbeat_result.get("code") == 0:
            logger.info("自动心跳已开启")
        else:
            logger.error(f"开启自动心跳失败: {heartbeat_result.get('Message', '未知错误')}")
    except Exception as e:
        logger.error(f"开启自动心跳异常: {e}")

def generate_wechat_qr_code():
    """生成微信登录二维码"""
    import time
    now = time.time()
    try:
        # 调用登录API生成二维码
        api_base_url = config_manager.api_config.api_base_url
        logger.info(f"使用API基础URL: {api_base_url}")
        
        # 测试API连接是否可用
        import requests
        try:
            # 先测试API服务器是否可访问
            test_url = api_base_url.split('/api')[0] if '/api' in api_base_url else api_base_url
            logger.info(f"测试API服务器连接: {test_url}")
            
            test_response = requests.get(test_url, timeout=5)
            logger.info(f"API服务器连接测试结果: 状态码={test_response.status_code}")
        except requests.exceptions.RequestException as conn_error:
            logger.error(f"API服务器连接失败: {conn_error}")
            return False
        
        login_api = LoginApi.init_no_wxid(api_base_url)
        
        # 使用login_get_qr_x方法代替不存在的login_get_qr
        device_name = config_manager.api_config.device_name
        device_id = config_manager.api_config.device_id
        logger.info(f"调用login_get_qr_x，设备名称: {device_name}, 设备ID: {device_id}")
        
        try:
            qr_result = login_api.login_get_qr_x(device_name=device_name, device_id=device_id)
            logger.info(f"API返回原始结果: {qr_result}")
        except Exception as api_error:
            logger.error(f"调用login_get_qr_x API失败: {api_error}")
            # 尝试直接访问API
            import requests
            try:
                body = {
                    "DeviceID": device_id or f"device-{device_name}",
                    "DeviceName": device_name,
                    "LoginType": "my Pad",
                    "Proxy": {}
                }
                
                # 确保URL格式正确
                api_url = f"{api_base_url}/Login/LoginGetQRx"
                # 确保URL中包含/api路径
                if '/api/' not in api_url and not api_url.endswith('/api'):
                    # 如果URL中不包含/api/，则在URL和路径之间添加/api
                    base_part = api_url.split('/Login/LoginGetQRx')[0]
                    api_url = f"{base_part}/api/Login/LoginGetQRx"
                
                logger.info(f"请求URL: {api_url}")
                logger.info(f"请求参数: {body}")
                
                response = requests.post(
                    api_url,
                    json=body,
                    timeout=10
                )
                logger.info(f"直接请求API状态码: {response.status_code}")
                logger.info(f"直接请求API响应内容: {response.text[:200]}")  # 只记录前200个字符
                qr_result = response.json()
            except requests.exceptions.ConnectionError as conn_error:
                logger.error(f"API连接失败: {conn_error}")
                return False
            except Exception as direct_error:
                logger.error(f"直接请求API也失败: {direct_error}")
                return False
        
        if qr_result.get("Success") or qr_result.get("Code") == 0:
            # 获取二维码信息
            data = qr_result.get("Data", {})
            uuid = data.get("uuid")
            qr_url = data.get("qrUrl")
            expires_in = data.get("expiresIn", 300)  # 默认5分钟过期
            
            logger.info(f"获取到二维码信息: uuid={uuid}, qr_url长度={len(qr_url) if qr_url else 0}")
            
            if not uuid or not qr_url:
                logger.error("二维码生成失败：缺少UUID或二维码URL")
                return False
            
            try:
                # 生成二维码图片
                import qrcode
                from io import BytesIO
                import base64
                
                qr = qrcode.QRCode(version=1, box_size=10, border=5)
                qr.add_data(qr_url)
                qr.make(fit=True)
                
                # 创建二维码图片
                img = qr.make_image(fill_color="black", back_color="white")
                
                # 转换为base64数据URL
                buffer = BytesIO()
                img.save(buffer, format='PNG')
                qr_code_base64 = base64.b64encode(buffer.getvalue()).decode()
                qr_code = f"data:image/png;base64,{qr_code_base64}"
                
                logger.info(f"二维码图片生成成功，base64长度: {len(qr_code_base64)}")
                
                wechat_login_status.update({
                    "qr_code": qr_code,
                    "qr_uuid": uuid,
                    "qr_code_expires": now + expires_in,
                    "last_check": now
                })
                
                logger.info(f"二维码生成成功，UUID: {uuid}")
                return True
            except Exception as qr_error:
                logger.error(f"生成二维码图片失败: {qr_error}")
                return False
        else:
            error_msg = qr_result.get("Message") or qr_result.get("msg", "未知错误")
            logger.error(f"生成二维码失败，API返回错误: {error_msg}")
            return False
            
    except Exception as e:
        logger.error(f"生成微信二维码失败: {e}")
        import traceback
        logger.error(traceback.format_exc())
        return False

@app.route('/test-static')
def test_static():
    """测试静态文件"""
    return render_template('test_static.html')

@app.route('/')
@login_required
def index():
    """主页"""
    return render_template('index.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    """登录页面"""
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        
        users_data = load_users()
        user_data = users_data.get("users", {}).get(username)
        
        if user_data and check_password_hash(user_data["password_hash"], password):
            user = User(username, username, user_data["password_hash"])
            login_user(user)
            return redirect(url_for('index'))
        else:
            return render_template('login.html', error='用户名或密码错误')
    
    return render_template('login.html')

@app.route('/logout')
@login_required
def logout():
    """登出"""
    logout_user()
    return redirect(url_for('login'))

@app.route('/api/config', methods=['GET', 'POST'])
@login_required
def api_config():
    """配置管理API"""
    if request.method == 'GET':
        try:
            config = config_manager.get_api_config()  # 每次都重新读取
            print(f"[DEBUG] /api/config 接口被调用")
            print(f"[DEBUG] 返回的配置: api_base_url={config.api_base_url}, device_name={config.device_name}, device_id={config.device_id}")
            return jsonify({"success": True, "data": {
                "api_base_url": config.api_base_url,
                "websocket_url": config.websocket_url,
                "device_name": config.device_name,
                "device_id": config.device_id,
                "logger_debug": config.logger_debug
            }})
        except Exception as e:
            print(f"[DEBUG] /api/config 接口异常: {e}")
            return jsonify({"success": False, "error": str(e)})
    
    elif request.method == 'POST':
        try:
            # 暂时不支持动态更新配置
            return jsonify({"success": False, "error": "暂不支持动态更新配置"})
        except Exception as e:
            return jsonify({"success": False, "error": str(e)})

def scan_plugins():
    """扫描plugins目录下的所有插件"""
    plugins = []
    plugins_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'plugins')
    
    if not os.path.exists(plugins_dir):
        return plugins
    
    # 扫描所有插件目录
    for plugin_dir in glob.glob(os.path.join(plugins_dir, '*/')):
        plugin_name = os.path.basename(os.path.dirname(plugin_dir))
        
        # 跳过非插件目录
        if plugin_name in ['__pycache__', 'base_plugin.py', 'plugin_manager.py', 'event_system.py', 'README.md']:
            continue
        
        config_file = os.path.join(plugin_dir, 'config.json')
        if not os.path.exists(config_file):
            continue
        
        try:
            with open(config_file, 'r', encoding='utf-8') as f:
                config = json.load(f)
            
            plugin_info = {
                "name": plugin_name,
                "display_name": config.get("name", plugin_name),
                "version": config.get("version", "1.0.0"),
                "description": config.get("description", ""),
                "author": config.get("author", "Unknown"),
                "enabled": config.get("enabled", False),
                "supported_message_types": config.get("supported_message_types", []),
                "settings": config.get("settings", {}),
                "config_file": config_file
            }
            plugins.append(plugin_info)
        except Exception as e:
            print(f"加载插件 {plugin_name} 配置失败: {e}")
            continue
    
    return plugins

def update_plugin_config(plugin_name, new_config):
    """更新插件配置"""
    plugins_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'plugins')
    config_file = os.path.join(plugins_dir, plugin_name, 'config.json')
    
    if not os.path.exists(config_file):
        return False
    
    try:
        with open(config_file, 'r', encoding='utf-8') as f:
            config = json.load(f)
        
        # 更新配置
        config.update(new_config)
        
        # 保存配置
        with open(config_file, 'w', encoding='utf-8') as f:
            json.dump(config, f, ensure_ascii=False, indent=4)
        
        return True
    except Exception as e:
        print(f"更新插件 {plugin_name} 配置失败: {e}")
        return False

@app.route('/api/plugins', methods=['GET'])
@login_required
def api_plugins():
    """插件管理API"""
    try:
        plugins = scan_plugins()
        return jsonify({"success": True, "data": plugins})
    except Exception as e:
        return jsonify({"success": False, "error": str(e)})

@app.route('/api/plugins/<plugin_name>/toggle', methods=['POST'])
@login_required
def api_toggle_plugin(plugin_name):
    """切换插件状态"""
    try:
        plugins = scan_plugins()
        plugin = next((p for p in plugins if p["name"] == plugin_name), None)
        
        if not plugin:
            return jsonify({"success": False, "error": "插件不存在"})
        
        # 切换启用状态
        new_enabled = not plugin["enabled"]
        success = update_plugin_config(plugin_name, {"enabled": new_enabled})
        
        if success:
            return jsonify({
                "success": True, 
                "data": {"enabled": new_enabled},
                "message": f"插件已{'启用' if new_enabled else '禁用'}"
            })
        else:
            return jsonify({"success": False, "error": "更新插件状态失败"})
    except Exception as e:
        return jsonify({"success": False, "error": str(e)})

@app.route('/api/plugins/<plugin_name>/config', methods=['GET', 'POST'])
@login_required
def api_plugin_config(plugin_name):
    """插件配置API"""
    try:
        plugins = scan_plugins()
        plugin = next((p for p in plugins if p["name"] == plugin_name), None)
        
        if not plugin:
            return jsonify({"success": False, "error": "插件不存在"})
        
        if request.method == 'GET':
            return jsonify({
                "success": True, 
                "data": {
                    "name": plugin["display_name"],
                    "version": plugin["version"],
                    "description": plugin["description"],
                    "author": plugin["author"],
                    "enabled": plugin["enabled"],
                    "supported_message_types": plugin["supported_message_types"],
                    "settings": plugin["settings"]
                }
            })
        else:
            # POST - 更新配置
            data = request.json
            if not data:
                return jsonify({"success": False, "error": "无效的配置数据"})
            
            # 只允许更新settings和enabled
            update_data = {}
            if "settings" in data:
                update_data["settings"] = data["settings"]
            if "enabled" in data:
                update_data["enabled"] = data["enabled"]
            
            success = update_plugin_config(plugin_name, update_data)
            
            if success:
                return jsonify({
                    "success": True,
                    "message": "配置更新成功"
                })
            else:
                return jsonify({"success": False, "error": "配置更新失败"})
    except Exception as e:
        return jsonify({"success": False, "error": str(e)})

@app.route('/api/wechat/status')
@login_required
def api_wechat_status():
    """获取微信登录状态"""
    print("=" * 50)
    print("DEBUG: /api/wechat/status 接口被调用")
    print("=" * 50)
    logger.info("=" * 50)
    logger.info("DEBUG: /api/wechat/status 接口被调用")
    logger.info("=" * 50)
    
    try:
        # 直接返回全局状态变量，确保一致性
        logger.info(f"wechat_login_status全局变量: {wechat_login_status}")
        
        result = {
            "success": True,
            "data": {
                "is_logged_in": wechat_login_status["is_logged_in"],
                "wxid": wechat_login_status["wxid"],
                "user_info": wechat_login_status["user_info"],
                "last_check": wechat_login_status["last_check"]
            }
        }
        
        logger.info(f"最终返回结果: {result}")
        print(f"DEBUG: 实际返回的JSON数据: {result}")
        
        # 确保返回正确的数据
        response = jsonify(result)
        logger.info(f"jsonify后的响应: {response.get_data(as_text=True)}")
        return response
    except Exception as e:
        logger.error(f"api_wechat_status异常: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({"success": False, "error": str(e)})

@app.route('/api/wechat/qrcode')
@login_required
def api_wechat_qrcode():
    """获取微信登录二维码"""
    try:
        # 检查当前登录状态，不进行自动检查
        if wechat_login_status["is_logged_in"]:
            return jsonify({
                "success": True,
                "data": {
                    "is_logged_in": True,
                    "user_info": wechat_login_status["user_info"],
                    "message": "微信已登录，无需二维码"
                }
            })
        
        # 直接调用API获取二维码
        api_base_url = config_manager.api_config.api_base_url
        device_name = config_manager.api_config.device_name
        device_id = config_manager.api_config.device_id
        
        logger.info(f"直接调用API获取二维码: {api_base_url}")
        logger.info(f"设备信息: 名称={device_name}, ID={device_id}")
        
        import requests
        import qrcode
        from io import BytesIO
        import base64
        import time
        
        # 构造请求参数
        body = {
            "DeviceID": device_id or f"device-{device_name}",
            "DeviceName": device_name,
            "LoginType": "my Pad",
            "Proxy": {}
        }
        
        # 确保URL格式正确
        api_url = f"{api_base_url}/Login/LoginGetQRx"
        # 确保URL中包含/api路径
        if '/api/' not in api_url and not api_url.endswith('/api'):
            # 如果URL中不包含/api/，则在URL和路径之间添加/api
            base_part = api_url.split('/Login/LoginGetQRx')[0]
            api_url = f"{base_part}/api/Login/LoginGetQRx"
        
        logger.info(f"请求URL: {api_url}")
        logger.info(f"请求参数: {body}")
        
        # 发送请求
        response = requests.post(
            api_url,
            json=body,
            timeout=15
        )
        
        logger.info(f"API响应状态码: {response.status_code}")
        
        # 检查响应
        if response.status_code != 200:
            logger.error(f"API响应错误: {response.status_code}")
            return jsonify({
                "success": False,
                "error": f"API响应错误: {response.status_code}"
            })
        
        # 解析响应
        try:
            qr_result = response.json()
            logger.info(f"API响应内容: {qr_result}")
        except Exception as json_error:
            logger.error(f"解析JSON响应失败: {json_error}")
            return jsonify({
                "success": False,
                "error": f"解析JSON响应失败: {json_error}"
            })
        
        # 检查响应结果
        if qr_result.get("Success") or qr_result.get("Code") == 0:
            # 获取二维码信息
            data = qr_result.get("Data", {})
            uuid = data.get("Uuid")
            qr_url = data.get("QrUrl")
            if 'data=' in qr_url:
                qr_url = qr_url.split('data=')[1]
            expires_in = data.get("expiresIn", 300)  # 默认5分钟过期
            
            logger.info(f"获取到二维码信息: uuid={uuid}, qr_url长度={len(qr_url) if qr_url else 0}")
            
            if not uuid or not qr_url:
                logger.error("二维码生成失败：缺少UUID或二维码URL")
                return jsonify({
                    "success": False,
                    "error": "二维码生成失败：缺少UUID或二维码URL"
                })
            
            # 生成二维码图片
            qr = qrcode.QRCode(version=1, box_size=10, border=5)
            qr.add_data(qr_url)
            qr.make(fit=True)
            
            # 创建二维码图片
            img = qr.make_image(fill_color="black", back_color="white")
            
            # 转换为base64数据URL
            buffer = BytesIO()
            img.save(buffer, format='PNG')
            qr_code_base64 = base64.b64encode(buffer.getvalue()).decode()
            qr_code = f"data:image/png;base64,{qr_code_base64}"
            
            logger.info(f"二维码图片生成成功，base64长度: {len(qr_code_base64)}")
            
            # 更新登录状态
            now = time.time()
            wechat_login_status.update({
                "qr_code": qr_code,
                "qr_uuid": uuid,
                "qr_code_expires": now + expires_in,
                "last_check": now
            })
            
            return jsonify({
                "success": True,
                "data": {
                    "qr_code": qr_code,
                    "uuid": uuid,
                    "expires_in": int(expires_in),
                    "is_logged_in": False
                }
            })
        else:
            error_msg = qr_result.get("Message") or qr_result.get("msg", "未知错误")
            logger.error(f"生成二维码失败，API返回错误: {error_msg}")
            return jsonify({
                "success": False,
                "error": f"生成二维码失败: {error_msg}"
            })
    except requests.exceptions.ConnectionError as conn_error:
        logger.error(f"连接API服务器失败: {conn_error}")
        return jsonify({
            "success": False,
            "error": f"连接API服务器失败: {conn_error}"
        })
    except Exception as e:
        logger.error(f"生成二维码失败: {e}")
        import traceback
        logger.error(traceback.format_exc())
        return jsonify({
            "success": False,
            "error": f"生成二维码失败: {e}"
        })

@app.route('/api/wechat/check')
@login_required
def api_wechat_check():
    """检查微信登录状态（轮询）"""
    try:
        # 从请求参数中获取UUID
        uuid = request.args.get('uuid')
        
        # 检查登录状态
        status = check_wechat_login_status(uuid)
        
        # 如果已登录，清除二维码
        if status["is_logged_in"]:
            wechat_login_status["qr_code"] = None
            wechat_login_status["qr_code_expires"] = None
        
        return jsonify({
            "success": True,
            "data": {
                "is_logged_in": status["is_logged_in"],
                "wxid": status["wxid"],
                "user_info": status["user_info"],
                "last_check": status["last_check"]
            }
        })
    except Exception as e:
        return jsonify({"success": False, "error": str(e)})

@app.route('/api/users', methods=['GET', 'POST', 'DELETE'])
@login_required
def api_users():
    """用户管理API"""
    if request.method == 'GET':
        try:
            users_data = load_users()
            users = []
            for user_id, user_data in users_data.get("users", {}).items():
                users.append({
                    "id": user_id,
                    "username": user_data["username"],
                    "created_at": user_data.get("created_at", "")
                })
            return jsonify({"success": True, "data": users})
        except Exception as e:
            return jsonify({"success": False, "error": str(e)})
    
    elif request.method == 'POST':
        try:
            data = request.json
            username = data.get("username")
            password = data.get("password")
            
            if not username or not password:
                return jsonify({"success": False, "error": "用户名和密码不能为空"})
            
            users_data = load_users()
            if username in users_data.get("users", {}):
                return jsonify({"success": False, "error": "用户已存在"})
            
            users_data["users"][username] = {
                "username": username,
                "password_hash": generate_password_hash(password),
                "created_at": datetime.now().isoformat()
            }
            save_users(users_data)
            
            return jsonify({"success": True, "message": "用户创建成功"})
        except Exception as e:
            return jsonify({"success": False, "error": str(e)})
    
    elif request.method == 'DELETE':
        try:
            user_id = request.args.get("user_id")
            if not user_id:
                return jsonify({"success": False, "error": "用户ID不能为空"})
            
            users_data = load_users()
            if user_id not in users_data.get("users", {}):
                return jsonify({"success": False, "error": "用户不存在"})
            
            if user_id == "admin":
                return jsonify({"success": False, "error": "不能删除默认管理员账户"})
            
            del users_data["users"][user_id]
            save_users(users_data)
            
            return jsonify({"success": True, "message": "用户删除成功"})
        except Exception as e:
            return jsonify({"success": False, "error": str(e)})

@app.route('/api/system/status')
@login_required
def api_system_status():
    """获取系统状态"""
    try:
        # 使用check_wechat_login_status()函数获取最新状态
        login_status = check_wechat_login_status()
        wechat_status = login_status.get("is_logged_in", False)
        
        # 模拟插件信息
        plugins = []  # 暂时返回空列表
        enabled_plugins = 0
        
        # 模拟系统信息
        try:
            import psutil
            system_info = {
                "cpu_usage": psutil.cpu_percent(),
                "memory_usage": psutil.virtual_memory().percent,
                "disk_usage": psutil.disk_usage('/').percent,
                "uptime": time.time() - psutil.boot_time(),
                "plugin_count": len(plugins),
                "enabled_plugins": enabled_plugins,
                "wechat_status": wechat_status
            }
        except ImportError:
            # 如果没有psutil，返回模拟数据
            system_info = {
                "cpu_usage": 25.0,
                "memory_usage": 60.0,
                "disk_usage": 45.0,
                "uptime": 3600,
                "plugin_count": len(plugins),
                "enabled_plugins": enabled_plugins,
                "wechat_status": wechat_status
            }
        
        return jsonify({
            "success": True,
            "data": system_info
        })
    except Exception as e:
        return jsonify({"success": False, "error": str(e)})

# ==================== 群组相关API ====================
@app.route('/api/groups', methods=['GET'])
@login_required
def get_groups():
    """获取所有群组信息"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        wxid = login_status.get("wxid")
        if not wxid:
            return jsonify({"success": False, "message": "无法获取wxid"})
        
        # 使用好友API获取通讯录列表（包含群组）

        friend_api = FriendApi.init()
        group_api = GroupApi.init()
        
        async def get_contract_list():
            return await friend_api.friend_get_contract_list()
        
        # 运行异步函数
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            contract_result = loop.run_until_complete(get_contract_list())
        finally:
            loop.close()
        if not contract_result or contract_result.get("Code") != 0:
            return jsonify({"success": False, "message": "获取通讯录列表失败"})
        user_name_list = contract_result.get("Data", {}).get("ContactUsernameList", [])
        detailed_groups = []
        if not user_name_list:
            return jsonify({"success": True, "data": []})
        # 如果有群组，尝试获取详细信息
        for qid in user_name_list:
            if not '@chatroom' in qid:
                continue
            async def get_group_detail():
                return await group_api.group_get_chat_room_info(wxid, qid)

            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            try:
                detail_result = loop.run_until_complete(get_group_detail())
            finally:
                loop.close()

            contact_list = detail_result.get("Data", {}).get("ContactList", [])
            if (detail_result.get("Success") or detail_result.get("Code") == 0) and contact_list:
                detail_data = contact_list[0]
                detailed_group = {
                    "qid": qid,
                    "group_name": detail_data.get("NickName", {}).get("string", ""),
                    "member_count": detail_data.get("NewChatroomData", {}).get("MemberCount", 0),
                    "owner": detail_data.get("ChatRoomOwner", ""),
                    "last_update": datetime.now().isoformat()
                }
                detailed_groups.append(detailed_group)
        return jsonify({
            "success": True,
            "data": detailed_groups,
            "message": f"获取到 {len(detailed_groups)} 个群组"
        })
    except Exception as e:
        logger.error(f"获取群组信息失败:",e)
        return jsonify({"success": False, "message": f"获取群组信息失败: {str(e)}"})

@app.route('/api/groups/<qid>', methods=['GET'])
@login_required
def get_group_detail(qid):
    """获取群组详细信息"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        wxid = login_status.get("wxid")
        if not wxid:
            return jsonify({"success": False, "message": "无法获取wxid"})
        
        # 调用API获取群组详情
        api_base_url = config_manager.api_config.api_base_url
        group_api = GroupApi.init_no_wxid(api_base_url)
        
        async def get_group_details():
            # 获取群信息详情
            info_result = await group_api.group_get_chat_room_info(wxid, qid)
            return  info_result
        
        # 运行异步函数
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
             info_result = loop.run_until_complete(get_group_details())
        finally:
            loop.close()
        
        group_detail = {
            "qid": qid,
            "info_detail": info_result.get('Data',{}).get('ContactList', [])[0]
        }
        
        return jsonify({
            "success": True,
            "data": group_detail,
            "message": "获取群组详情成功"
        })
            
    except Exception as e:
        logger.error(f"获取群组详情失败: {str(e)}")
        return jsonify({"success": False, "message": f"获取群组详情失败: {str(e)}"})

# ==================== 好友相关API ====================
@app.route('/api/friends', methods=['GET'])
@login_required
def get_friends():
    """获取所有好友信息"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        wxid = login_status.get("wxid")
        if not wxid:
            return jsonify({"success": False, "message": "无法获取wxid"})
        
        # 尝试从数据库获取好友列表，如果API调用失败
        try:
            # 调用API获取好友列表
            async def get_contract_list():
                # 使用较长的超时和多次重试
                return await FriendApi.init().friend_get_contract_list(timeout=60, retries=3)
            
            # 运行异步函数
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            try:
                contract_result = loop.run_until_complete(get_contract_list())
            finally:
                loop.close()
            
            if contract_result.get("Success") or contract_result.get("Code") == 0:
                data = contract_result.get("Data", {})
                contact_username_list = data.get("ContactUsernameList", [])
                
                # 如果有用户名列表，获取详细信息
                friends = []
                if contact_username_list:
                    # 分批获取好友详情，每次最多20个
                    batch_size = 20
                    for i in range(0, len(contact_username_list), batch_size):
                        batch_wxids = contact_username_list[i:i + batch_size]
                        towxids_str = ",".join(batch_wxids)  # 转换为逗号分隔的字符串
                        
                        async def get_friend_details():
                            # 使用较长的超时和多次重试
                            return await FriendApi.init().friend_get_contract_detail(towxids_str, timeout=60, retries=3)
                        
                        loop = asyncio.new_event_loop()
                        asyncio.set_event_loop(loop)
                        try:
                            detail_result = loop.run_until_complete(get_friend_details())
                        except Exception as e:
                            logger.error(f"获取好友详情批次 {i//batch_size + 1} 失败: {str(e)}")
                            # 如果获取详情失败，使用基本信息
                            for username in batch_wxids:
                                friend_info = {
                                    "wxid": username,
                                    "nickname": username,
                                    "remark": "",
                                    "last_update": datetime.now().isoformat()
                                }
                                friends.append(friend_info)
                            continue
                        finally:
                            loop.close()
                        
                        if detail_result.get("Success") or detail_result.get("Code") == 0:
                            detail_data = detail_result.get("Data", {})
                            contact_list = detail_data.get("ContactList", [])
                            
                            for contact in contact_list:
                                # 正确处理嵌套对象结构
                                wxid_value = contact.get("UserName", {})
                                if isinstance(wxid_value, dict) and "string" in wxid_value:
                                    wxid_value = wxid_value["string"]
                                elif isinstance(wxid_value, dict):
                                    wxid_value = ""  # 空字典转换为空字符串
                                avatar_url=contact.get("SmallHeadImgUrl", '')
                                nickname_value = contact.get("NickName", {})
                                if isinstance(nickname_value, dict) and "string" in nickname_value:
                                    nickname_value = nickname_value["string"]
                                elif isinstance(nickname_value, dict):
                                    nickname_value = ""  # 空字典转换为空字符串
                                
                                remark_value = contact.get("Remark", {})
                                if isinstance(remark_value, dict) and "string" in remark_value:
                                    remark_value = remark_value["string"]
                                elif isinstance(remark_value, dict):
                                    remark_value = ""  # 空字典转换为空字符串
                                
                                friend_info = {
                                    "wxid": wxid_value,
                                    "nickname": nickname_value,
                                    "remark": remark_value,
                                    "last_update": datetime.now().isoformat()
                                }
                                friends.append(friend_info)
                                
                                # 保存到数据库
                                try:
                                    async def save_to_db():
                                        from database.messsagDB import MessageDB
                                        db = MessageDB()
                                        await db.save_friend_info(
                                            wxid=wxid_value,
                                            nickname=nickname_value,
                                            remark=remark_value,
                                            avatar_url=avatar_url,
                                        )
                                    
                                    loop = asyncio.new_event_loop()
                                    asyncio.set_event_loop(loop)
                                    try:
                                        loop.run_until_complete(save_to_db())
                                    finally:
                                        loop.close()
                                except Exception as e:
                                    logger.warning(f"保存好友信息到数据库失败: {e}")
                        else:
                            # 如果获取详情失败，使用用户名列表
                            for username in batch_wxids:
                                friend_info = {
                                    "wxid": username,
                                    "nickname": username,
                                    "remark": "",
                                    "last_update": datetime.now().isoformat()
                                }
                                friends.append(friend_info)
                else:
                    # 如果没有用户名列表，尝试从WxContactList获取
                    wx_contact_list = data.get("WxContactList", [])
                    for contact in wx_contact_list:
                        # 正确处理嵌套对象结构
                        wxid_value = contact.get("UserName", {})
                        if isinstance(wxid_value, dict) and "string" in wxid_value:
                            wxid_value = wxid_value["string"]
                        elif isinstance(wxid_value, dict):
                            wxid_value = ""  # 空字典转换为空字符串
                        
                        nickname_value = contact.get("NickName", {})
                        if isinstance(nickname_value, dict) and "string" in nickname_value:
                            nickname_value = nickname_value["string"]
                        elif isinstance(nickname_value, dict):
                            nickname_value = ""  # 空字典转换为空字符串
                        
                        remark_value = contact.get("Remark", {})
                        if isinstance(remark_value, dict) and "string" in remark_value:
                            remark_value = remark_value["string"]
                        elif isinstance(remark_value, dict):
                            remark_value = ""  # 空字典转换为空字符串
                        
                        friend_info = {
                            "wxid": wxid_value,
                            "nickname": nickname_value,
                            "remark": remark_value,
                            "last_update": datetime.now().isoformat()
                        }
                        friends.append(friend_info)
                        
                        # 保存到数据库
                        try:
                            async def save_to_db():
                                from database.messsagDB import MessageDB
                                db = MessageDB()
                                await db.save_friend_info(
                                    wxid=wxid_value,
                                    nickname=nickname_value,
                                    remark=remark_value,
                                    avatar_url=avatar_url
                                )
                            
                            loop = asyncio.new_event_loop()
                            asyncio.set_event_loop(loop)
                            try:
                                loop.run_until_complete(save_to_db())
                            finally:
                                loop.close()
                        except Exception as e:
                            logger.warning(f"保存好友信息到数据库失败: {e}")
                
                return jsonify({
                    "success": True,
                    "data": friends,
                    "message": f"获取到 {len(friends)} 个好友"
                })
            else:
                # API调用失败，尝试从数据库获取
                raise Exception(f"API调用失败: {contract_result.get('Message', '未知错误')}")
        
        except Exception as api_error:
            logger.error(f"从API获取好友信息失败，尝试从数据库获取: {str(api_error)}")
            
            # 从数据库获取好友列表
            async def get_friends_from_db():
                from database.messsagDB import MessageDB
                db = MessageDB()
                return await db.get_all_friends()
            
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            try:
                friends = loop.run_until_complete(get_friends_from_db())
                if friends:
                    return jsonify({
                        "success": True,
                        "data": friends,
                        "message": f"从数据库获取到 {len(friends)} 个好友 (API调用失败)"
                    })
                else:
                    return jsonify({
                        "success": False,
                        "message": f"获取好友失败: API调用失败，数据库中也没有好友信息"
                    })
            except Exception as db_error:
                logger.error(f"从数据库获取好友信息也失败: {str(db_error)}")
                return jsonify({
                    "success": False,
                    "message": f"获取好友失败: API和数据库都无法获取好友信息"
                })
            finally:
                loop.close()
            
    except Exception as e:
        logger.error(f"获取好友信息失败: {str(e)}")
        return jsonify({"success": False, "message": f"获取好友信息失败: {str(e)}"})

@app.route('/api/friends/search', methods=['GET'])
@login_required
def search_friends():
    """搜索好友（从数据库）"""
    try:
        keyword = request.args.get('keyword', '').strip()
        if not keyword:
            return jsonify({"success": False, "message": "请输入搜索关键词"})
        
        # 从数据库搜索好友
        async def search_from_db():
            from database.messsagDB import MessageDB
            db = MessageDB()
            friends = await db.get_all_friends()
            
            # 过滤匹配的好友
            matched_friends = []
            for friend in friends:
                if (keyword.lower() in friend.wxid.lower() or 
                    keyword.lower() in friend.nickname.lower() or 
                    keyword.lower() in (friend.remark or '').lower()):
                    matched_friends.append({
                        "wxid": friend.wxid,
                        "nickname": friend.nickname,
                        "remark": friend.remark,
                        "last_update": friend.last_update.isoformat() if friend.last_update else None
                    })
            
            return matched_friends
        
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            friends = loop.run_until_complete(search_from_db())
        finally:
            loop.close()
        
        return jsonify({
            "success": True,
            "data": friends,
            "message": f"找到 {len(friends)} 个匹配的好友"
        })
        
    except Exception as e:
        logger.error(f"搜索好友失败: {str(e)}")
        return jsonify({"success": False, "message": f"搜索好友失败: {str(e)}"})

@app.route('/api/friends/list', methods=['GET'])
@login_required
def get_friends_from_db():
    """从数据库获取好友列表（用于下拉选择）"""
    try:
        # 从数据库获取好友列表
        async def get_from_db():
            from database.messsagDB import MessageDB
            db = MessageDB()
            friends = await db.get_all_friends()
            
            # 转换为前端需要的格式
            friends_list = []
            for friend in friends:
                friends_list.append({
                    "wxid": friend.wxid,
                    "nickname": friend.nickname,
                    "remark": friend.remark,
                    "display_name": friend.remark if friend.remark else friend.nickname
                })
            
            return friends_list
        
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            friends = loop.run_until_complete(get_from_db())
        finally:
            loop.close()
        
        return jsonify({
            "success": True,
            "data": friends,
            "message": f"获取到 {len(friends)} 个好友"
        })
        
    except Exception as e:
        logger.error(f"从数据库获取好友列表失败: {str(e)}")
        return jsonify({"success": False, "message": f"获取好友列表失败: {str(e)}"})

@app.route('/api/friends/<wxid>', methods=['GET'])
@login_required
def get_friend_detail(wxid):
    """获取好友详细信息"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        current_wxid = login_status.get("wxid")
        if not current_wxid:
            return jsonify({"success": False, "message": "无法获取wxid"})
        
        logger.info(f"获取好友详情 - 当前用户: {current_wxid}, 目标好友: {wxid}")
        
        # 调用API获取好友详情 - 注意：towxids必须是逗号分隔的字符串
        api_base_url = config_manager.api_config.api_base_url
        friend_api = FriendApi.init_no_wxid(api_base_url)
        
        async def get_friend_details():
            return await friend_api.friend_get_contract_detail(current_wxid, wxid)
        
        # 运行异步函数
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            detail_result = loop.run_until_complete(get_friend_details())
        finally:
            loop.close()
        
        logger.info(f"好友详情API响应: {detail_result}")
        
        if detail_result.get("Success") or detail_result.get("Code") == 0:
            data = detail_result.get("Data", {})
            contact_list = data.get("ContactList", [])
            
            if contact_list and len(contact_list) > 0:
                contact = contact_list[0]  # 取第一个联系人
                
                # 正确处理嵌套对象结构
                wxid_value = contact.get("UserName", {})
                if isinstance(wxid_value, dict) and "string" in wxid_value:
                    wxid_value = wxid_value["string"]
                elif isinstance(wxid_value, dict):
                    wxid_value = ""
                
                nickname_value = contact.get("NickName", {})
                if isinstance(nickname_value, dict) and "string" in nickname_value:
                    nickname_value = nickname_value["string"]
                elif isinstance(nickname_value, dict):
                    nickname_value = ""
                
                remark_value = contact.get("Remark", {})
                if isinstance(remark_value, dict) and "string" in remark_value:
                    remark_value = remark_value["string"]
                elif isinstance(remark_value, dict):
                    remark_value = ""
                
                friend_detail = {
                    "wxid": wxid_value,
                    "nickname": nickname_value,
                    "remark": remark_value,
                    "phone": contact.get("Phone", ""),
                    "email": contact.get("Email", ""),
                    "last_update": datetime.now().isoformat()
                }
                
                return jsonify({
                    "success": True,
                    "data": friend_detail,
                    "message": "获取好友详情成功"
                })
            else:
                return jsonify({
                    "success": False,
                    "message": "未找到好友详情"
                })
        else:
            return jsonify({
                "success": False,
                "message": f"获取好友详情失败: {detail_result.get('Message', '未知错误')}"
            })
            
    except Exception as e:
        logger.error(f"获取好友详情失败: {str(e)}")
        return jsonify({"success": False, "message": f"获取好友详情失败: {str(e)}"})

@app.route('/api/friends/<wxid>/remark', methods=['POST'])
@login_required
def set_friend_remark(wxid):
    """设置好友备注"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        current_wxid = login_status.get("wxid")
        if not current_wxid:
            return jsonify({"success": False, "message": "无法获取wxid"})
        
        data = request.get_json()
        remark = data.get("remark", "")
        
        # 调用API设置备注
        api_base_url = config_manager.api_config.api_base_url
        friend_api = FriendApi.init_no_wxid(api_base_url)
        
        async def set_remark():
            return await friend_api.friend_set_remarks(current_wxid, wxid, remark)
        
        # 运行异步函数
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            result = loop.run_until_complete(set_remark())
        finally:
            loop.close()
        
        if result.get("Success") or result.get("Code") == 0:
            return jsonify({
                "success": True,
                "message": "设置备注成功"
            })
        else:
            return jsonify({
                "success": False,
                "message": f"设置备注失败: {result.get('Message', '未知错误')}"
            })
            
    except Exception as e:
        logger.error(f"设置好友备注失败: {str(e)}")
        return jsonify({"success": False, "message": f"设置好友备注失败: {str(e)}"})

# ==================== 聊天记录相关API ====================
@app.route('/api/chat/history', methods=['GET'])
@login_required
def get_chat_history():
    """获取聊天记录"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        wxid = login_status.get("wxid")
        if not wxid:
            return jsonify({"success": False, "message": "无法获取wxid"})
        
        # 获取查询参数
        chat_type = request.args.get("type", "friend")
        target = request.args.get("target", "")
        
        # 从数据库查询聊天记录
        try:
            # 初始化数据库连接
            async def get_chat_records():
                from database.messsagDB import MessageDB
                db = MessageDB()
                await db.initialize()
                
                if target:
                    # 如果指定了目标，查询特定聊天记录
                    if chat_type == "friend":
                        records = await db.get_chat_records(f"{wxid}_{target}", limit=50)
                    else:
                        records = await db.get_chat_records(f"{target}", limit=50)
                else:
                    # 如果没有指定目标，获取所有聊天记录
                    records = await db.get_messages(limit=100)
                
                return records
            
            # 运行异步函数
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            try:
                records = loop.run_until_complete(get_chat_records())
            finally:
                loop.close()
            
            # 格式化记录
            messages = []
            for record in records:
                messages.append({
                    "id": record.id,
                    "msg_id": record.msg_id,
                    "sender_wxid": record.sender_wxid,
                    "from_wxid": getattr(record, 'from_wxid', ''),
                    "content": record.content,
                    "msg_type": record.msg_type,
                    "timestamp": record.timestamp.isoformat() if record.timestamp else "",
                    "is_self": record.sender_wxid == wxid
                })
            
            return jsonify({
                "success": True,
                "data": messages,
                "message": f"获取到 {len(messages)} 条聊天记录"
            })
            
        except Exception as e:
            logger.error(f"查询聊天记录失败: {str(e)}")
            return jsonify({
                "success": False,
                "message": f"查询聊天记录失败: {str(e)}"
            })
            
    except Exception as e:
        logger.error(f"获取聊天记录失败: {str(e)}")
        return jsonify({"success": False, "message": f"获取聊天记录失败: {str(e)}"})

@app.route('/api/chat/search', methods=['GET'])
@login_required
def search_chat_records():
    """搜索聊天记录"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        # 获取搜索参数
        keyword = request.args.get('keyword', '')
        chat_id = request.args.get('chat_id', '')
        start_date = request.args.get('start_date', '')
        end_date = request.args.get('end_date', '')
        limit = request.args.get('limit', 100, type=int)
        
        # 从数据库搜索聊天记录
        async def search_records():
            db = MessageDB()
            await db.initialize()
            
            # 构建查询条件
            start_time = None
            end_time = None
            
            if start_date:
                start_time = datetime.fromisoformat(start_date)
            if end_date:
                end_time = datetime.fromisoformat(end_date)
            
            # 获取所有消息
            all_messages = await db.get_messages(
                start_time=start_time,
                end_time=end_time,
                limit=1000  # 获取更多消息进行搜索
            )
            
            # 在Python中进行关键词搜索
            matched_messages = []
            for msg in all_messages:
                if chat_id and msg.from_wxid != chat_id:
                    continue
                if keyword and keyword.lower() not in msg.content.lower():
                    continue
                matched_messages.append(msg)
                if len(matched_messages) >= limit:
                    break
            
            return matched_messages
        
        # 运行异步函数
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            records = loop.run_until_complete(search_records())
        finally:
            loop.close()
        
        # 格式化记录
        formatted_records = []
        for record in records:
            formatted_records.append({
                "id": record.id,
                "msg_id": record.msg_id,
                "sender_wxid": record.sender_wxid,
                "from_wxid": record.from_wxid,
                "content": record.content,
                "msg_type": record.msg_type,
                "timestamp": record.timestamp.isoformat(),
                "is_group": record.is_group
            })
        
        # 根据是否有关键词返回不同的消息
        if keyword:
            message = f"搜索到 {len(formatted_records)} 条相关记录"
        else:
            message = f"获取到 {len(formatted_records)} 条聊天记录"
        
        return jsonify({
            "success": True,
            "data": formatted_records,
            "message": message
        })
            
    except Exception as e:
        logger.error(f"搜索聊天记录失败: {str(e)}")
        return jsonify({"success": False, "message": f"搜索聊天记录失败: {str(e)}"})

# ==================== 消息发送相关API ====================
@app.route('/api/message/send', methods=['POST'])
@login_required
def send_message():
    """发送消息"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        wxid = login_status.get("wxid")
        if not wxid:
            return jsonify({"success": False, "message": "无法获取wxid"})
        
        data = request.get_json()
        to_wxid = data.get("to_wxid")
        content = data.get("content")
        msg_type = data.get("msg_type", 1)  # 默认文本消息
        at_users = data.get("at_users", "")
        
        if not to_wxid or not content:
            return jsonify({"success": False, "message": "缺少必要参数"})
        
        # 调用API发送消息
        api_base_url = config_manager.api_config.api_base_url
        msg_api = MsgApi.init_no_wxid(api_base_url)
        
        async def send_msg():
            if msg_type == 1:  # 文本消息
                return await msg_api.msg_send_txt(wxid, to_wxid, content, at_users)
            else:
                return {"success": False, "message": "暂不支持该消息类型"}
        
        # 运行异步函数
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            result = loop.run_until_complete(send_msg())
        finally:
            loop.close()
        
        if result.get("Success") or result.get("Code") == 0:
            return jsonify({
                "success": True,
                "message": "消息发送成功"
            })
        else:
            return jsonify({
                "success": False,
                "message": f"消息发送失败: {result.get('Message', '未知错误')}"
            })
            
    except Exception as e:
        logger.error(f"发送消息失败: {str(e)}")
        return jsonify({"success": False, "message": f"发送消息失败: {str(e)}"})

@app.route('/api/message/send_image', methods=['POST'])
@login_required
def send_image():
    """发送图片消息"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        wxid = login_status.get("wxid")
        if not wxid:
            return jsonify({"success": False, "message": "无法获取wxid"})
        
        data = request.get_json()
        to_wxid = data.get("to_wxid")
        image_base64 = data.get("image_base64")
        
        if not to_wxid or not image_base64:
            return jsonify({"success": False, "message": "缺少必要参数"})
        
        # 调用API发送图片
        api_base_url = config_manager.api_config.api_base_url
        msg_api = MsgApi.init_no_wxid(api_base_url)
        
        # 这里需要根据实际的图片发送API进行调整
        # result = msg_api.msg_send_cdn_img(wxid, to_wxid, image_base64)
        
        return jsonify({
            "success": False,
            "message": "图片发送功能暂未实现"
        })
            
    except Exception as e:
        logger.error(f"发送图片失败: {str(e)}")
        return jsonify({"success": False, "message": f"发送图片失败: {str(e)}"})

@app.route('/test-friends-debug')
@login_required
def test_friends_debug():
    """好友管理功能测试页面"""
    return render_template('test_friends_debug.html')

# ==================== 聊天记录管理API ====================
@app.route('/api/chat/list', methods=['GET'])
@login_required
def get_chat_list():
    """获取聊天记录列表"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        # 获取查询参数
        chat_type = request.args.get('type', '')  # group, private, all
        
        # 从数据库查询聊天列表
        async def get_chat_list_from_db():
            from database.messsagDB import MessageDB
            db = MessageDB()
            await db.initialize()
            return await db.get_chat_list(chat_type)

        # 运行异步函数
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            chat_list = loop.run_until_complete(get_chat_list_from_db())
        finally:
            loop.close()
        
        return jsonify({
            "success": True,
            "data": chat_list,
            "message": f"获取到 {len(chat_list)} 个聊天"
        })
        
    except Exception as e:
        logger.error(f"获取聊天列表失败: {str(e)}")
        return jsonify({"success": False, "message": f"获取聊天列表失败: {str(e)}"})

@app.route('/api/chat/detail/<chat_id>', methods=['GET'])
@login_required
def get_chat_detail(chat_id):
    """获取指定聊天的详细消息记录"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        # 获取查询参数
        limit = request.args.get('limit', 100, type=int)
        
        # 从数据库查询聊天详情
        async def get_chat_detail_from_db():
            from database.messsagDB import MessageDB
            db = MessageDB()
            await db.initialize()
            
            # 获取聊天记录
            messages = await db.get_messages_by_chat_id(chat_id, limit)
            chat_name=messages[0].from_nickname if messages else chat_id
            # 获取聊天对象信息
            chat_info = {}
            if chat_id.startswith('@chatroom'):  # 群聊
                group_info = await db.get_group_info(chat_id)

                if group_info:
                    chat_info = {
                        'chat_id': chat_id,
                        'chat_name': chat_name,
                        'chat_type': 'group',
                        'member_count': group_info.get('member_count', 0),
                        'owner_wxid': group_info.get('owner_wxid', ''),
                        'announcement': group_info.get('announcement', ''),
                        'members': group_info.get('members', [])
                    }
                else:
                    chat_info = {
                        'chat_id': chat_id,
                        'chat_name': chat_name,
                        'chat_type': 'group',
                        'member_count': 0,
                        'owner_wxid': '',
                        'announcement': '',
                        'members': []
                    }
            else:  # 私聊
                friend_info = await db.get_friend_info(chat_id)
                if friend_info:
                    chat_info = {
                        'chat_id': chat_id,
                        'chat_name': chat_name,
                        'chat_type': 'private',
                        'avatar': friend_info.get('avatar_url', ''),
                        'phone': friend_info.get('phone', ''),
                        'email': friend_info.get('email', '')
                    }
                else:
                    chat_info = {
                        'chat_id': chat_id,
                        'chat_name': chat_name,
                        'chat_type': 'private',
                        'avatar': '',
                        'phone': '',
                        'email': ''
                    }
            
            # 格式化消息数据
            formatted_messages = []
            for msg in messages:
                formatted_messages.append({
                    'id': msg.id,
                    'sender_wxid': msg.from_wxid,
                    'sender_nickname': msg.sender_nickname,
                    'content': msg.content,
                    'msg_type': msg.msg_type,
                    'timestamp': msg.timestamp.isoformat() if msg.timestamp else None,
                    'is_group': msg.is_group if hasattr(msg, 'is_group') else False
                })
            
            return {
                'chat_info': chat_info,
                'messages': formatted_messages
            }
        
        # 运行异步函数
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            result = loop.run_until_complete(get_chat_detail_from_db())
        finally:
            loop.close()
        
        return jsonify({
            "success": True,
            "data": result,
            "message": f"获取到 {len(result['messages'])} 条消息"
        })
        
    except Exception as e:
        logger.error(f"获取聊天详情失败: {str(e)}")
        return jsonify({"success": False, "message": f"获取聊天详情失败: {str(e)}"})

@app.route('/api/chat/statistics', methods=['GET'])
@login_required
def get_chat_statistics():
    """获取消息统计信息"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        # 从数据库查询统计信息
        async def get_statistics_from_db():
            from database.messsagDB import MessageDB
            db = MessageDB()
            await db.initialize()
            return await db.get_message_statistics()
        
        # 运行异步函数
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            statistics = loop.run_until_complete(get_statistics_from_db())
        finally:
            loop.close()
        
        return jsonify({
            "success": True,
            "data": statistics,
            "message": "获取统计信息成功"
        })
        
    except Exception as e:
        logger.error(f"获取统计信息失败: {str(e)}")
        return jsonify({"success": False, "message": f"获取统计信息失败: {str(e)}"})

@app.route('/api/chat/group/<group_id>/members', methods=['GET'])
@login_required
def get_group_members(group_id):
    """获取群成员列表"""
    try:
        # 检查微信登录状态
        login_status = check_wechat_login_status()
        if not login_status.get("is_logged_in"):
            return jsonify({"success": False, "message": "微信未登录"})
        
        # 从数据库查询群成员
        async def get_members_from_db():
            from database.messsagDB import MessageDB
            db = MessageDB()
            await db.initialize()
            return await db.get_group_members(group_id)
        
        # 运行异步函数
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            members = loop.run_until_complete(get_members_from_db())
        finally:
            loop.close()
        
        return jsonify({
            "success": True,
            "data": members,
            "message": f"获取到 {len(members)} 个群成员"
        })
        
    except Exception as e:
        logger.error(f"获取群成员失败: {str(e)}")
        return jsonify({"success": False, "message": f"获取群成员失败: {str(e)}"})

@app.route('/chat-records')
@login_required
def chat_records():
    """聊天记录管理页面"""
    logger.info("访问聊天记录路由")
    return render_template('chat_records.html')

@app.route('/friends')
@login_required
def friends():
    """好友列表页面"""
    logger.info("访问好友列表路由")
    return render_template('friends.html')

@app.route('/groups')
@login_required
def groups():
    """群聊管理页面"""
    logger.info("访问群聊管理路由")
    return render_template('groups.html')

@app.route('/plugins')
@login_required
def plugins():
    """插件管理页面"""
    logger.info("访问插件管理路由")
    return render_template('plugins.html')

@app.route('/settings')
@login_required
def settings():
    """系统设置页面"""
    logger.info("访问系统设置路由")
    return render_template('settings.html')

@app.route('/users')
@login_required
def users():
    """用户管理页面"""
    logger.info("访问用户管理路由")
    return render_template('users.html')

@app.route('/profile')
@login_required
def profile():
    """个人资料页面"""
    logger.info("访问个人资料路由")
    return render_template('profile.html')
